<?php

namespace App\Chat\Cache;

use App\Chat\Cache\Repository\HashRedis;
use Hyperf\Coroutine\Parallel;

/**
 * 私信消息未读数 - 缓存助手
 *
 * @package App\Chat\Cache
 */
class UnreadTalkCache extends HashRedis
{
    public $name = 'unread-talk';

    /**
     * 消息未读数自增
     * @param mixed $robotId
     * @param int $talkType
     * @param mixed $receive
     * @return void
     */
    public function increment(mixed $userId,mixed $robotId,int $talkType, mixed $receive)
    {
        $this->incr($this->flag($receive, $talkType, $userId, $robotId), 1);
    }

    /**
     * 读取消息未读数
     * @param mixed $robotId
     * @param int $talkType
     * @param mixed $receive
     * @return int
     */
    public function read( mixed $userId,mixed $robotId,int $talkType, mixed $receive): int
    {
        return (int)$this->get($this->flag($receive, $talkType, $userId, $robotId));
    }

    /**
     * 消息未读数清空
     * @param mixed $robotId
     * @param int $talkType
     * @param mixed $receive
     * @return void
     */
    public function reset( mixed $userId,mixed $robotId,int $talkType , mixed $receive)
    {
        $this->rem($this->flag($receive, $talkType, $userId, $robotId));
    }

    /**
     * 获取 Hash 成员 key
     * @param mixed $receive
     * @param int $talkType
     * @param mixed $robotId
     * @return string
     */
    public function flag(mixed $receive, int $talkType, mixed $userId, mixed$robotId): string
    {
        $flag = sprintf("%s_%s_%s_%s", $receive, $talkType, $userId, $robotId);
        return $flag;
    }

    /**
     * 读取指定用户的未读消息列表
     *
     * @param mixed $user_id 用户ID
     * @return array
     */
    public function reads(mixed $user_id): array
    {
        $iterator = null;
        $arr      = [];
        while ($elements = $this->redis()->hscan($this->getCacheKey(), $iterator, '*_' . $user_id.'_*', 20)) {
            foreach ($elements as $key => $value) {
                $arr[explode('_', $key)[0]] = $value;
            }
        }

        return $arr;
    }

    /**
     * 获取机器人未读消息数量
     * @param array $robotIds
     * @return array
     */
    public function getRobotUnreadNum(mixed $userId,array $robotIds): array
    {

        $parallel = new Parallel(10);

        foreach ($robotIds as $robotId){
            $parallel->add(function () use ($userId,$robotId) {
                $iterator = null;
                $unreadNum = 0;
                while ($elements = $this->redis()->hscan($this->getCacheKey(), $iterator, '*_*_'.$userId.'_'.$robotId, 20)) {
                    foreach ($elements as $value) {
                        $unreadNum = $unreadNum + $value;
                    }
                }
                return [
                    'robot_id' => $robotId,
                    'num' => $unreadNum
                ];
            });
        }

        $results = $parallel->wait();

        $robotMap = [];
        foreach ($results as $result){
            $robotMap[$result['robot_id']] = $result['num'];
        }

        return $robotMap;
    }
}
